package com.ys.service.account.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSON;
import com.ys.config.MenuId;
import com.ys.dto.AddDto;
import com.ys.entity.account.TcwAdvanceAccount;
import com.ys.entity.account.TcwAdvanceAccountBack;
import com.ys.entity.account.TcwAdvanceAccountDetail;
import com.ys.entity.account.TcwAdvanceAccountRecharge;
import com.ys.entity.business.TbBaseInfo;
import com.ys.entity.finance.TcwPartnerBankInfo;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.ThrOperateCompanyApply;
import com.ys.entity.sys.TsUserBankInfo;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.enume.finance.TcwFinancialTransactionFlowEnum;
import com.ys.enume.flow.FlowEnum;
import com.ys.mapper.account.TcwAdvanceAccountBackMapper;
import com.ys.mapper.account.TcwAdvanceAccountDetailMapper;
import com.ys.service.account.TcwAdvanceAccountBackService;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.finance.TcwFinancialTransactionFlowService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.CheckUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("tcwAdvanceAccountBackService")
public class TcwAdvanceAccountBackServiceImpl implements TcwAdvanceAccountBackService {

    @Autowired
    private TcwAdvanceAccountBackMapper tcwAdvanceAccountBackMapper;

    @Autowired
    private TcwAdvanceAccountDetailMapper tcwAdvanceAccountDetailMapper;

    @Autowired
    private CheckUtil checkUtil;

    @Autowired
    private YspTaskService yspTaskService;

    @Autowired
    private TcwAccountDetailedForCompanyService tcwAccountDetailedForCompanyService;
    @Autowired
    private TcwFinancialTransactionFlowService tcwFinancialTransactionFlowService;



    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R add(Map<String, Object> params, String subData) throws Exception {
        //验证
        String msg = yzMsg(params);
        if (msg != null){
            return R.error(msg);
        }
        TcwAdvanceAccountBack tcwAdvanceAccountBack = JSON.parseObject(JSON.toJSONString(params), TcwAdvanceAccountBack.class);
        if (new TcwAdvanceAccountBack().setBid(tcwAdvanceAccountBack.getBid()).count() != 0){
            return R.error("该单号已存在，核实后再操作!");
        }

        String loginUserId = ShiroUtils.getUserId();
        TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();

        tcwAdvanceAccountBack.setStatus(0);
        tcwAdvanceAccountBack.setCreateChangeId(tsUserChange.getId());
        tcwAdvanceAccountBack.setEffectStock(FlowEnum.EffectStock.NOT_EFFECT.value);
        tcwAdvanceAccountBackMapper.insert(tcwAdvanceAccountBack);


        YsMenu ysMenu = new YsMenu().setId(MenuId.TCW_AdvanceAccountBack).queryFirst();
        if (ysMenu.getFlowModelId().longValue() != 0L) {
            YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
            String codeModel = yspModel.getCode();
            String createUserId = ShiroUtils.getUserId();
            yspTaskService.init(codeModel, tcwAdvanceAccountBack.getBid(), createUserId);
        }

        return R.ok(AddDto.gotoEdit("/web/account/tcwAdvanceAccountBack/toEdit?bid=" + tcwAdvanceAccountBack.getBid()));
    }

    /**
     * 修改预支账户归还
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R edit(Map<String, Object> params,String subData) throws Exception {

        //验证
        String msg = yzMsg(params);
        if (msg != null){
            return R.error(msg);
        }
        TcwAdvanceAccountBack tcwAdvanceAccountBack = JSON.parseObject(JSON.toJSONString(params), TcwAdvanceAccountBack.class);
        if (new TcwAdvanceAccountBack().setBid(tcwAdvanceAccountBack.getBid()).where("A.id != " + tcwAdvanceAccountBack.getId()).count() != 0){
            return R.error("该单号已存在，核实后再操作!");
        }


        //判断是否实在制单中
        Integer flowState = yspTaskService.flowState(tcwAdvanceAccountBack.getBid());

        if (flowState != 0){
            return R.error("预支账户归还单不是制单中,不允许保存!");
        }
        tcwAdvanceAccountBackMapper.update(tcwAdvanceAccountBack);

        return R.ok(AddDto.gotoEdit("/web/account/tcwAdvanceAccountBack/toEdit?bid=" + tcwAdvanceAccountBack.getBid()));
    }


    /**
     * 流转
     * @param id
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowPass(Long id, String loginUserId) throws Exception {
        TcwAdvanceAccountBack entity = new TcwAdvanceAccountBack().setId(id).queryFirst();
        String bid = entity.getBid();
        try {
            Flow f = yspTaskService.flowPass(bid, loginUserId);
            if (f.getCode() == Flow.Code.FAILED.value) {
                return R.error(f.getMsg());
            } else {

                if (f.getState() == Flow.State.FINISH.value) {
                    R r = flowFinish(entity);
                    if (r.getCode() == 1) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return R.error(r.getMsg());
                    }
                }
                return R.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务器正在开小差，请联系客服");
        }
    }


    /**
     * 驳回
     * @param id
     * @param reason
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowRefuse(Long id, String reason, String loginUserId) throws Exception {
        try {
            TcwAdvanceAccountBack entity = new TcwAdvanceAccountBack().setId(id).queryFirst();
            String bid = entity.getBid();
            R r = yspTaskService.flowRefuse(bid, reason, loginUserId);
            if (r.getCode() == 1){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return R.error(r.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务器正在开小差，请联系客服");
        }
        return R.ok();
    }

    //删除
    @Override
    @Transactional
    public R del(Long id) throws Exception{
        if (id == null) {
            return R.error("ID不能为空");
        }
        TcwAdvanceAccountBack entity = new TcwAdvanceAccountBack().setId(id).queryFirst();
        if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
            return R.error("已生效数据无法删除");
        }
        // 验证是否制单人
        String loginUserId = ShiroUtils.getUserId();
        TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
        if (!tsUserChange.getUserId().equals(loginUserId) && !"admin".equals(loginUserId)) {
            return R.error("非制单人，无法删除");
        }
        //删除
        tcwAdvanceAccountBackMapper.deleteTrue(id);
        //删除流程
        yspTaskService.flowDelete(entity.getBid(), loginUserId);
        return R.ok();
    }

    private String yzMsg(Map<String, Object> infoMap){
        //验证导入字段
        String backMsg = "";
        //获取pc字段数据
        List<YsCol> listField = new YsCol()
                .where("A.MenuId = "+ MenuId.TCW_AdvanceAccountBack)
                .setOrderby("A.SortNo ASC")
                .queryList();
        //验证必填字段的非空；其他字段的长度限制、类型
        try {
            backMsg = checkUtil.checkTableColLengthAndDataType(
                    "TCW_AdvanceAccountBack",
                    listField,
                    infoMap,
                    ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1
            );
            if(backMsg!=null && !"".equals(backMsg)){//若有误，则跳过这条信息
                return backMsg;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public R flowFinish(TcwAdvanceAccountBack entity) throws Exception {
        Date date = new Date();
        entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
        entity.setUpdateTime(date);
        tcwAdvanceAccountBackMapper.update(entity);


        TcwAdvanceAccountRecharge tcwAdvanceAccountRecharge = new TcwAdvanceAccountRecharge().setId(entity.getAdvanceAccountRechargeId()).queryFirst();
        if(tcwAdvanceAccountRecharge!=null) {

            //新增一条流水
            ThrOperateCompanyApply thrOperateCompanyApply = new ThrOperateCompanyApply().setVgsbm(tcwAdvanceAccountRecharge.getVgsbm()).queryFirst();
            TcwAdvanceAccount tcwAdvanceAccount = new TcwAdvanceAccount().setId(tcwAdvanceAccountRecharge.getAdvanceAccountId()).queryFirst();
            if(thrOperateCompanyApply!=null && tcwAdvanceAccount!=null){
                //新增流水
                tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyWithJc(
                        tcwAdvanceAccountRecharge.getVgsbm(),thrOperateCompanyApply.getVgsjc(),tcwAdvanceAccount.getCode(),tcwAdvanceAccount.getName(),
                        tcwAdvanceAccountRecharge.getVjylx(),tcwAdvanceAccountRecharge.getRechargePrice(),entity.getCreateTime(), date,"预支账户归还单"+entity.getBid(),
                        entity.getBid(),date);
            }


            //新增台账明细
            TcwAdvanceAccountDetail tcwAdvanceAccountDetail = new TcwAdvanceAccountDetail();
            Long userChangeId = null;
            //获取制单人信息
            TsUserChange tsUserChange = new TsUserChange().setUserId(ShiroUtils.getUserId()).setOrderby("A.CreateTime DESC").queryFirst();
            if(tsUserChange!=null){
                userChangeId = tsUserChange.getId();//制单人变更信息
                tcwAdvanceAccountDetail.setCreateChangeId(userChangeId);
            }
            tcwAdvanceAccountDetail.setPid(tcwAdvanceAccountRecharge.getAdvanceAccountId());
            tcwAdvanceAccountDetail.setCreateChangeId(entity.getCreateChangeId());
            tcwAdvanceAccountDetail.setCompanyInfoVid(tcwAdvanceAccountRecharge.getCompanyVid());//所属公司vid
            tcwAdvanceAccountDetail.setAdvanceTypeCode("YZZHLX000");//充值类型
            tcwAdvanceAccountDetail.setVjylx(tcwAdvanceAccountRecharge.getVjylx());//交易类型名称
            tcwAdvanceAccountDetail.setDetailName("预支账户归还单"+entity.getBid());//名称
            tcwAdvanceAccountDetail.setUnitPrice(BigDecimal.ZERO.subtract(tcwAdvanceAccountRecharge.getRechargePrice()));//充值金额
            tcwAdvanceAccountDetail.setQuantity(new BigDecimal(1));//数量
            tcwAdvanceAccountDetail.setTotalPrice(BigDecimal.ZERO.subtract(tcwAdvanceAccountRecharge.getRechargePrice()));//总额
            tcwAdvanceAccountDetail.setRemark(entity.getRemark());//备注
            tcwAdvanceAccountDetail.setStatus(1);
            tcwAdvanceAccountDetail.setFromId(entity.getId());
            tcwAdvanceAccountDetail.setFromType(2);
            tcwAdvanceAccountDetail.setTransferStatus(1);

            tcwAdvanceAccountDetailMapper.insert(tcwAdvanceAccountDetail);


            //获取业务交易类型信息
            String transactionTypeStr = tcwAdvanceAccountRecharge.getVjylx();
            TbBaseInfo transactionTypeItem = tcwFinancialTransactionFlowService.getTransactionType(transactionTypeStr);

            //财务交易流水
            if(transactionTypeItem!=null && transactionTypeItem.getId()!=null){
                String vyhzhmc = "";
                String vkhh = "";
                String vyhzh = "";
                if(tcwAdvanceAccount ==null){
                    throw new IllegalArgumentException("未查询到对应的预支账户管理信息");
                }
                if(tcwAdvanceAccount.getAccountType()==0){
                    TsUserBankInfo tsUserBankInfo = new TsUserBankInfo().setId(tcwAdvanceAccount.getUserBankInfoId()).queryFirst();
                    if(tsUserBankInfo!=null && tsUserBankInfo.getVyhzhmc()!=null){
                        vyhzhmc = tsUserBankInfo.getVyhzhmc();
                        vkhh = tsUserBankInfo.getVkhh();
                        vyhzh = tsUserBankInfo.getVyhzh();
                    }else {
                        throw new IllegalArgumentException("未查询到对应的银行账户名称信息");
                    }
                }else {
                    TcwPartnerBankInfo tcwPartnerBankInfo = new TcwPartnerBankInfo().setId(tcwAdvanceAccount.getPartnerBankInfoId()).queryFirst();
                    if(tcwPartnerBankInfo!=null && tcwPartnerBankInfo.getVyhzhmc()!=null){
                        vyhzhmc = tcwPartnerBankInfo.getVyhzhmc();
                        vkhh = tcwPartnerBankInfo.getVkhh();
                        vyhzh = tcwPartnerBankInfo.getVyhzh();
                    }else {
                        throw new IllegalArgumentException("未查询到对应的银行账户名称信息");
                    }
                }
                R res = tcwFinancialTransactionFlowService.add(true,
                        tcwAdvanceAccountRecharge.getCompanyBankInfoId(), transactionTypeItem.getBid(),
                        vyhzhmc,vkhh, vyhzh,
                        tcwAdvanceAccountRecharge.getRechargePrice(),
                        entity.getCreateTime(),date,new Date(),"预支账户归还单"+entity.getBid()+entity.getRemark(),
                        TcwFinancialTransactionFlowEnum.FromType.TCW_AdvanceAccountBack.value,entity.getId());
                if(res.getCode().equals( R.Code.FAILED.value)){
                    throw new IllegalArgumentException(res.getMsg());
                }
            }

        }


        return R.ok();
    }


    //获取列表数据
    @Override
    @Transactional
    public Map<String,Object> getExtraParam( String bid) throws Exception{
        Map<String,Object> entity = new TcwAdvanceAccountBack().setBid(bid)
                .addLeftJoin("TCW_AdvanceAccountRecharge aar ON aar.id = A.advanceAccountRechargeId ")
                .addField("aar.bid AS advanceAccountRechargeBid,aar.id advanceAccountRechargeId,aar.rechargePrice rechargePrice,aar.vjylx vjylx,aar.rechargePrice returnPrice")//充值单信息
                .addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
                .addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd hh:mm:ss') AS auditingTime")//审核时间

                .addLeftJoin("TS_UserChange U ON U.Id = A.CreateChangeId ")
                .addField("U.UserId + '/' + U.UserName AS createUserName")//制单人

                .addLeftJoin("THR_OperateCompanyApply C ON C.Vgsbm = aar.Vgsbm ")
                .addField("C.Vgsjc AS vgsjc,C.vgsbm AS vgsbm")//运营公司

                .addLeftJoin("TB_CompanyInfo CI ON CI.Vid = aar.CompanyVid ")
                .addField("CI.Vname AS vname")//所属公司

                .addLeftJoin("TB_CompanyBankInfo CB ON CB.Id = aar.CompanyBankInfoId ")
                .addField("CB.Vyhzhmc AS vyhzhmc")//付款账户名称
                .addField("CB.Vyhzh AS vyhzh")//付款账号
                .addField("CB.Vkhh AS vkhh")//付款开户行

                .addLeftJoin("TCW_AdvanceAccount AA ON AA.Id = aar.AdvanceAccountId ")
                .addField("AA.Code AS code")//预支账户编码
                .addField("AA.Name AS name")//付款账户名称

                /*
        .addLeftJoin("TS_UserBankInfo UB ON AA.UserBankInfoId = UB.Id")
                .addLeftJoin("TS_UserInfo B on  B.UserId = UB.UserId")
                .addField("B.DeptName AS deptName")//账户管理部门
                .addField("B.RoleName AS roleName")//负责人岗位
                .addField("(B.UserId + '/' + B.UserName) AS nameLinked")//账户管理负责人
                .addField("UB.Vyhzhmc AS vyhzhmcByAdvance")//银行账户名称
                .addField("UB.Vkhh AS vkhhByAdvance")//开户行
                .addField("UB.Vyhzh AS vyhzhByAdvance")//银行账户编码
                 */


                .addLeftJoin("TS_UserInfo B on  B.UserId = AA.UserId")
                .addLeftJoin("TS_OrganizationInfo O on  O.Orgid = AA.Orgid")
                .addField("O.DeptName AS deptName")//账户管理部门
                .addField("B.RoleName AS roleName")//负责人岗位
                .addField("(B.UserId + '/' + B.UserName) AS nameLinked")//账户管理负责人

                .addLeftJoin("TS_UserBankInfo UB ON AA.UserBankInfoId = UB.Id AND AA.AccountType=0")
                .addLeftJoin("TCW_PartnerBankInfo PB ON AA.PartnerBankInfoId = PB.Id AND AA.AccountType=1")
                //.addField("CASE WHEN AA.AccountType=0 THEN U.Vyhzhmc ELSE P.Vyhzhmc END _ys_vyhzhmc")//银行账户名称
                //.addField("CASE WHEN AA.AccountType=0 THEN U.Vkhh ELSE P.Vkhh END _ys_vkhh")//开户行
                //.addField("CASE WHEN AA.AccountType=0 THEN U.Vyhzh ELSE P.Vyhzh END _ys_vyhzh")//银行账户编码

                .addField("CASE WHEN AA.AccountType=0 THEN UB.Vyhzhmc ELSE PB.Vyhzhmc END vyhzhmcByAdvance")//银行账户名称
                .addField("CASE WHEN AA.AccountType=0 THEN UB.Vkhh ELSE PB.Vkhh END vkhhByAdvance")//开户行
                .addField("CASE WHEN AA.AccountType=0 THEN UB.Vyhzh ELSE PB.Vyhzh END vyhzhByAdvance")//银行账户编码

                //明细1
                .addLeftJoin("(SELECT Pid, SUM(TotalPrice) AS totalPriceByRecharge FROM TCW_AdvanceAccountDetail  WHERE AdvanceTypeCode ='YZZHLX000' GROUP BY Pid) D1 on D1.Pid = aar.AdvanceAccountId AND 1=1")
                .addField("ISNULL(D1.totalPriceByRecharge, 0) AS totalPriceByRecharge")//账户备用金额,字段“总额”之和（预支类型为充值）


                .queryFirstMap();
        return entity;
    }



}
